package com.nft.sms.service;

import javax.validation.Valid;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.teaopenapi.models.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import com.nft.common.vo.PageResult;
import com.nft.constants.Constant;
import com.nft.sms.domain.SmsSendRecord;
import com.nft.sms.param.SmsSendRecordQueryCondParam;
import com.nft.sms.repo.SmsSendRecordRepo;
import com.nft.sms.vo.SmsSendRecordVO;
import com.zengtengpeng.annotation.Lock;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Validated
@Service
public class SmsService {

	@Autowired
	private SmsSendRecordRepo smsSendRecordRepo;
	@Value("${aliyun.accessKeyId}")
	private String ALIBABA_CLOUD_ACCESS_KEY_ID;
	@Value("${aliyun.accessKeySecret}")
	private String ALIBABA_CLOUD_ACCESS_KEY_SECRET;
	@Value("${aliyun.templateCode}")
	private String TemplateCode;

	@Transactional(readOnly = true)
	public PageResult<SmsSendRecordVO> findSendRecordByPage(@Valid SmsSendRecordQueryCondParam param) {
		Specification<SmsSendRecord> spec = param.buildSpecification();
		Page<SmsSendRecord> result = smsSendRecordRepo.findAll(spec,
				PageRequest.of(param.getPageNum() - 1, param.getPageSize(), Sort.by(Sort.Order.desc("createTime"))));
		PageResult<SmsSendRecordVO> pageResult = new PageResult<>(SmsSendRecordVO.convertFor(result.getContent()),
				param.getPageNum(), param.getPageSize(), result.getTotalElements());
		return pageResult;
	}

	@Lock(keys = "'sendSms' + #id")
	@Transactional
	public void sendSms(String id) {
		SmsSendRecord smsSendRecord = smsSendRecordRepo.getOne(id);
		if (Constant.短信发送状态_发送成功.equals(smsSendRecord.getState())) {
			return;
		}
		try {
			// 这里调短信接口
			String code = sendSmsAliyun(smsSendRecord.getMobile(),smsSendRecord);
			if(code !=null){
				smsSendRecord.success();
			}else {
				smsSendRecord.fail("短信发送失败");
			}

		} catch (Exception e) {
			log.error("短信接口异常:" + e.getMessage());
			smsSendRecord.fail("短信接口异常");
		}
		smsSendRecordRepo.save(smsSendRecord);
	}


	public String sendSmsAliyun(String phone,SmsSendRecord smsSendRecord) throws Exception {
		// 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
		// 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
		com.aliyun.dysmsapi20170525.Client client = createClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET);
		String code = smsSendRecord.getVerificationCode();
		com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
				.setSignName("上海梵先伦贸易")
				.setTemplateCode(TemplateCode)
				.setPhoneNumbers(phone)
				.setTemplateParam("{\"code\":\"" + code + "\"}");
		com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
		com.aliyun.dysmsapi20170525.models.SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);
		com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(resp));
		if (resp.getBody().getCode().equals("OK")) {
			return code;
		}
		return null;
	}
	public Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
		Config config = new com.aliyun.teaopenapi.models.Config()
				// 必填，您的 AccessKey ID
				.setAccessKeyId(accessKeyId)
				// 必填，您的 AccessKey Secret
				.setAccessKeySecret(accessKeySecret);
		// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
		config.endpoint = "dysmsapi.aliyuncs.com";
		return new Client(config);
	}



}
